home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / ADA / GNAT / !gcc / adainc / 2 / adb / a-wtenau < prev    next >
Text File  |  1996-02-12  |  11KB  |  365 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT RUNTIME COMPONENTS                          --
  4. --                                                                          --
  5. --                ADA.TEXT_IO.WIDE_TEXT_IO.ENUMERATION_AUX                  --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.2 $                              --
  10. --                                                                          --
  11. --     Copyright (C) 1992,1993,1994, 1995 Free Software Foundation, Inc.    --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
  22. -- MA 02111-1307, USA.                                                      --
  23. --                                                                          --
  24. -- As a special exception,  if other files  instantiate  generics from this --
  25. -- unit, or you link  this unit with other files  to produce an executable, --
  26. -- this  unit  does not  by itself cause  the resulting  executable  to  be --
  27. -- covered  by the  GNU  General  Public  License.  This exception does not --
  28. -- however invalidate  any other reasons why  the executable file  might be --
  29. -- covered by the  GNU Public License.                                      --
  30. --                                                                          --
  31. -- GNAT was originally developed  by the GNAT team at  New York University. --
  32. -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
  33. --                                                                          --
  34. ------------------------------------------------------------------------------
  35.  
  36. with Ada.Text_IO.Generic_Aux; use Ada.Text_IO.Generic_Aux;
  37. with Ada.Characters.Handling; use Ada.Characters.Handling;
  38. with Interfaces.C_Streams;    use Interfaces.C_Streams;
  39. with System.File_IO;          use System.File_IO;
  40. with System.WCh_Con;          use System.WCh_Con;
  41.  
  42. package body Ada.Text_IO.Wide_Text_IO.Enumeration_Aux is
  43.  
  44.    subtype TFT is Ada.Text_IO.File_Type;
  45.    --  File type required for calls to routines in Aux
  46.  
  47.    -----------------------
  48.    -- Local Subprograms --
  49.    -----------------------
  50.  
  51.    procedure Store_Char
  52.      (File : File_Type;
  53.       WC   : Wide_Character;
  54.       Buf  : out Wide_String;
  55.       Ptr  : in out Integer);
  56.    --  Store a single character in buffer, checking for overflow.
  57.  
  58.    --  These definitions replace the ones in Ada.Characters.Handling, which
  59.    --  do not seem to work for some strange not understood reason ??? at
  60.    --  least in the OS/2 version.
  61.  
  62.    function To_Lower (C : Character) return Character;
  63.    function To_Upper (C : Character) return Character;
  64.  
  65.    function To_Lower (C : Character) return Character is
  66.    begin
  67.       if C in 'A' .. 'Z' then
  68.          return Character'Val (Character'Pos (C) + 32);
  69.       else
  70.          return C;
  71.       end if;
  72.    end To_Lower;
  73.  
  74.    function To_Upper (C : Character) return Character is
  75.    begin
  76.       if C in 'a' .. 'z' then
  77.          return Character'Val (Character'Pos (C) - 32);
  78.       else
  79.          return C;
  80.       end if;
  81.    end To_Upper;
  82.  
  83.    ------------------
  84.    -- Get_Enum_Lit --
  85.    ------------------
  86.  
  87.    procedure Get_Enum_Lit
  88.      (File   : File_Type;
  89.       Buf    : out Wide_String;
  90.       Buflen : out Natural)
  91.    is
  92.       ch  : int;
  93.       WC  : Wide_Character;
  94.  
  95.    begin
  96.       Buflen := 0;
  97.       Load_Skip (TFT (File));
  98.       ch := Nextc (TFT (File));
  99.  
  100.       --  Character literal case. If the initial character is a quote, then
  101.       --  we read as far as we can without backup (see ACVC test CE3905L)
  102.  
  103.       if ch = Character'Pos (''') then
  104.          Get (File, WC);
  105.          Store_Char (File, WC, Buf, Buflen);
  106.  
  107.          ch := Nextc (TFT (File));
  108.  
  109.          if ch = LM or else ch = EOF then
  110.             return;
  111.          end if;
  112.  
  113.          Get (File, WC);
  114.          Store_Char (File, WC, Buf, Buflen);
  115.  
  116.          ch := Nextc (TFT (File));
  117.  
  118.          if ch /= Character'Pos (''') then
  119.             return;
  120.          end if;
  121.  
  122.          Get (File, WC);
  123.          Store_Char (File, WC, Buf, Buflen);
  124.  
  125.       --  Similarly for identifiers, read as far as we can, in particular,
  126.       --  do read a trailing underscore (again see ACVC test CE3905L to
  127.       --  understand why we do this, although it seems somewhat peculiar).
  128.  
  129.       else
  130.          --  Identifier must start with a letter. Any wide character value
  131.          --  outside the normal Latin-1 range counts as a letter for this.
  132.  
  133.          if ch < 255 and then not Is_Letter (Character'Val (ch)) then
  134.             return;
  135.          end if;
  136.  
  137.          --  If we do have a letter, loop through the characters quitting on
  138.          --  the first non-identifier character (note that this includes the
  139.          --  cases of hitting a line mark or page mark).
  140.  
  141.          loop
  142.             Get (File, WC);
  143.             Store_Char (File, WC, Buf, Buflen);
  144.  
  145.             ch := Nextc (TFT (File));
  146.  
  147.             exit when ch = EOF;
  148.  
  149.             if ch = Character'Pos ('_') then
  150.                exit when Buf (Buflen) = '_';
  151.  
  152.             elsif ch = Character'Pos (Ascii.ESC) then
  153.                null;
  154.  
  155.             elsif File.WC_Method in WC_Upper_Half_Encoding_Method
  156.               and then ch > 127
  157.             then
  158.                null;
  159.  
  160.             else
  161.                exit when Is_Letter (Character'Val (ch))
  162.                  and then not Is_Digit (Character'Val (ch));
  163.             end if;
  164.          end loop;
  165.       end if;
  166.    end Get_Enum_Lit;
  167.  
  168.    -------------------
  169.    -- Scan_Enum_Lit --
  170.    -------------------
  171.  
  172.    procedure Scan_Enum_Lit
  173.      (From  : Wide_String;
  174.       Start : out Natural;
  175.       Stop  : out Natural)
  176.    is
  177.       WC  : Wide_Character;
  178.  
  179.    --  Processing for Scan_Enum_Lit
  180.  
  181.    begin
  182.       Start := From'First;
  183.  
  184.       loop
  185.          if Start > From'Last then
  186.             raise End_Error;
  187.  
  188.          elsif Is_Character (From (Start))
  189.            and then not Is_Blank (To_Character (From (Start)))
  190.          then
  191.             exit;
  192.  
  193.          else
  194.             Start := Start + 1;
  195.          end if;
  196.       end loop;
  197.  
  198.       --  Character literal case. If the initial character is a quote, then
  199.       --  we read as far as we can without backup (see ACVC test CE3905L
  200.       --  which is for the analogous case for reading from a file).
  201.  
  202.       if From (Start) = ''' then
  203.          Stop := Start;
  204.  
  205.          if Stop = From'Last then
  206.             raise Data_Error;
  207.          else
  208.             Stop := Stop + 1;
  209.          end if;
  210.  
  211.          if From (Stop) in ' ' .. '~'
  212.            or else From (Stop) >= Wide_Character'Val (16#80#)
  213.          then
  214.             if Stop = From'Last then
  215.                raise Data_Error;
  216.             else
  217.                Stop := Stop + 1;
  218.  
  219.                if From (Stop) = ''' then
  220.                   return;
  221.                end if;
  222.             end if;
  223.          end if;
  224.  
  225.          Stop := Stop - 1;
  226.          raise Data_Error;
  227.  
  228.       --  Similarly for identifiers, read as far as we can, in particular,
  229.       --  do read a trailing underscore (again see ACVC test CE3905L to
  230.       --  understand why we do this, although it seems somewhat peculiar).
  231.  
  232.       else
  233.          --  Identifier must start with a letter, any wide character outside
  234.          --  the normal Latin-1 range is considered a letter for this test.
  235.  
  236.          if Is_Character (From (Start))
  237.            and then not Is_Letter (To_Character (From (Start)))
  238.          then
  239.             raise Data_Error;
  240.          end if;
  241.  
  242.          --  If we do have a letter, loop through the characters quitting on
  243.          --  the first non-identifier character (note that this includes the
  244.          --  cases of hitting a line mark or page mark).
  245.  
  246.          Stop := Start + 1;
  247.          while Stop < From'Last loop
  248.             WC := From (Stop + 1);
  249.  
  250.             exit when
  251.               Is_Character (WC)
  252.                 and then
  253.                   not Is_Letter (To_Character (WC))
  254.                 and then
  255.                   not Is_Letter (To_Character (WC))
  256.                 and then
  257.                   (WC /= '_' or else From (Stop - 1) = '_');
  258.  
  259.             Stop := Stop + 1;
  260.          end loop;
  261.       end if;
  262.  
  263.    end Scan_Enum_Lit;
  264.  
  265.    ---------
  266.    -- Put --
  267.    ---------
  268.  
  269.    procedure Put
  270.      (File  : File_Type;
  271.       Item  : Wide_String;
  272.       Width : Field;
  273.       Set   : Type_Set)
  274.    is
  275.       Actual_Width : constant Integer :=
  276.                        Integer'Max (Integer (Width), Item'Length);
  277.  
  278.    begin
  279.       Check_On_One_Line (TFT (File), Actual_Width);
  280.  
  281.       if Set = Lower_Case and then Item (1) /= ''' then
  282.          declare
  283.             Iteml : Wide_String (Item'First .. Item'Last);
  284.  
  285.          begin
  286.             for J in Item'Range loop
  287.                if Is_Character (Item (J)) then
  288.                   Iteml (J) :=
  289.                     To_Wide_Character (To_Lower (To_Character (Item (J))));
  290.                else
  291.                   Iteml (J) := Item (J);
  292.                end if;
  293.             end loop;
  294.  
  295.             Put (File, Iteml);
  296.          end;
  297.  
  298.       else
  299.          Put (File, Item);
  300.       end if;
  301.  
  302.       for J in 1 .. Actual_Width - Item'Length loop
  303.          Put (File, ' ');
  304.       end loop;
  305.    end Put;
  306.  
  307.    ----------
  308.    -- Puts --
  309.    ----------
  310.  
  311.    procedure Puts
  312.      (To    : out Wide_String;
  313.       Item  : in Wide_String;
  314.       Set   : Type_Set)
  315.    is
  316.       Ptr : Natural;
  317.  
  318.    begin
  319.       if Item'Length > To'Length then
  320.          raise Layout_Error;
  321.  
  322.       else
  323.          Ptr := To'First;
  324.          for J in Item'Range loop
  325.             if Set = Lower_Case
  326.               and then Item (1) /= '''
  327.               and then Is_Character (Item (J))
  328.             then
  329.                To (Ptr) :=
  330.                  To_Wide_Character (To_Lower (To_Character (Item (J))));
  331.             else
  332.                To (Ptr) := Item (J);
  333.             end if;
  334.  
  335.             Ptr := Ptr + 1;
  336.          end loop;
  337.  
  338.          while Ptr <= To'Last loop
  339.             To (Ptr) := ' ';
  340.             Ptr := Ptr + 1;
  341.          end loop;
  342.       end if;
  343.    end Puts;
  344.  
  345.    ----------------
  346.    -- Store_Char --
  347.    ----------------
  348.  
  349.    procedure Store_Char
  350.      (File : File_Type;
  351.       WC   : Wide_Character;
  352.       Buf  : out Wide_String;
  353.       Ptr  : in out Integer)
  354.    is
  355.    begin
  356.       if Ptr = Buf'Last then
  357.          raise Data_Error;
  358.       else
  359.          Ptr := Ptr + 1;
  360.          Buf (Ptr) := WC;
  361.       end if;
  362.    end Store_Char;
  363.  
  364. end Ada.Text_IO.Wide_Text_IO.Enumeration_Aux;
  365.